<?php
/**
 * 功能：支付宝生成二维码
 * 版本：v1.0
 * author：wangkk
 * 以下部分就是具体的生成二维码过程，只需要引入自己的配置文件$config数组信息，同时需要获取订单信息即可使用
 */

namespace app\api\controller;

use app\api\model\RechargeOrder;
use think\Db;
use think\Request;

class PayController  extends BaseController {

    public function __construct(){
        //配置项
        parent::__construct();
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/aop/AopClient.php';
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/aop/request/AlipayTradePrecreateRequest.php';
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/phpqrcode/phpqrcode.php';
        $alipay_config = config('alipay.');
        $this->gateway_url       = $alipay_config['gatewayUrl'];
        $this->appid             = $alipay_config['app_id'];
        $this->private_key       = $alipay_config['merchant_private_key'];
        $this->alipay_public_key = $alipay_config['alipay_public_key'];
        $this->charset           = $alipay_config['charset'];
        $this->signtype          = $alipay_config['sign_type'];
        $this->notify_url        = $alipay_config['notify_url'];
        $this->return_url        = $alipay_config['return_url'];
    }

    public function alipay(Request $request){
        //订单号，自定义，唯一
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/aop/AopClient.php';
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/aop/request/AlipayTradePrecreateRequest.php';
        include_once \think\facade\Env::get('EXTEND_PATH') . 'alipayqr/phpqrcode/phpqrcode.php';
        /** --------------------------------以上部分需要修改：获取订单信息 end--------------------------------- **/
        //订单测试信息
        $total_amount = $request->param('money', 11);
        $pay_type =$request->param('pay_type', 1);
        $body = '商品描述';         //商品描述，可为空
        $subject ='流量币';
        $out_trade_no    =  date('YmdHis') . rand(10000000, 99999999);//订单号，必填
        $alipay_config = config('alipay.');
        $aopObj = new \AopClient ();
        //设置值
        $aopObj->gatewayUrl = $alipay_config['gatewayUrl'];
        $aopObj->appId      = $alipay_config['app_id'];
        $aopObj->rsaPrivateKey =$alipay_config['merchant_private_key'];
        $aopObj->alipayrsaPublicKey = $alipay_config['alipay_public_key'];
        $aopObj->apiVersion = '1.0';
        $aopObj->postCharset =  $alipay_config['charset'];
        $aopObj->format = 'json';
        $aopObj->signType = $alipay_config['sign_type'];
        $request = new \AlipayTradePrecreateRequest();
        $save_data = [
            'member_id' => $this->userInfo->user_id,
            'pay_type' => $pay_type,
            'order_sn' => $out_trade_no,
            'pay_state' => '0',
            'amount' => $total_amount,
            'pay_source' => "支付宝网页支付",
            'add_time' => time(),
            'describe' => $body,
        ];
        $id = Db::name('recharge_order')->insertGetId($save_data);
        if (!$id) {
            $this->error('订单生成失败');
        }
        //组装订单数据
        $timeout_express = '5m';  //超时，1分钟
        $bizContentarr = array(
            'body'            => $body ? $body : '', //商品描述,可以为空
            'subject'         => $subject,
            'out_trade_no'    => $out_trade_no,
            'total_amount'    => $total_amount,
            'timeout_express' => $timeout_express,  //过期时间
        );
        $bizContent = json_encode($bizContentarr,JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizContent);
        $request->setNotifyUrl( $alipay_config['notify_url']);
        $request->setReturnUrl(  $alipay_config['return_url']);
        $result = $aopObj->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $result->$responseNode->code;

        if(!empty($resultCode) && $resultCode == 10000){
            //成功，得到二维码,不使用官方的方法
            $qr_code_url = $result->$responseNode->qr_code;
            $icon = './logo.png';//准备好的logo图片
            \QRcode::png($qr_code_url,false, 'H',  8, false);
            $code           = ob_get_clean();
            $code           = imagecreatefromstring($code);
            $logo           = imagecreatefrompng($icon);
            $QR_width       = imagesx($code);//二维码图片宽度
            $logo_width     = imagesx($logo);//logo图片宽度
            $logo_height    = imagesy($logo);//logo图片高度
            $logo_qr_width  = $QR_width / 4;
            $scale          = $logo_width/$logo_qr_width;
            $logo_qr_height = $logo_height/$scale;
            $from_width = ($QR_width - $logo_qr_width) / 2;
            //重新组合图片并调整大小
            imagecopyresampled($code, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);
            //打开缓冲区
            ob_start();
            header ( "Content-type: image/png" );
             ImagePng($code);
            $imageString = base64_encode(ob_get_contents());
            //关闭缓冲区
            ob_end_clean();
            $data = array(
                'code'=>200,
                'msg'=>time(),
                'data'=>$imageString
            );
            return json_encode($data,JSON_FORCE_OBJECT);
            die;
        } else {
            echo 'fail';die;
        }
    }

    public function return_url(){
        include_once \think\facade\Env::get('EXTEND_PATH').'alipayqr/service/AlipayTradeService.php';
        $config = config('alipay.');
        $arr = $_GET;
        $alipaySevice = new \AlipayTradeService($config);
        $alipaySevice->writeLog(var_export($arr,true));
        $result = $alipaySevice->check($arr);

        /* 实际验证过程建议商户添加以下校验。
        1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
        2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
        3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email）
        4、验证app_id是否为该商户本身。
        */
        if($result) {//验证成功
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代
            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
            //商户订单号
            $out_trade_no = $_POST['out_trade_no'];
            //支付宝交易号
            $trade_no = $_POST['trade_no'];
            //交易状态
            $trade_status = $_POST['trade_status'];
            if($_POST['trade_status'] == 'TRADE_FINISHED') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
            }
            else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_amount与通知时获取的total_fee为一致的
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //付款完成后，支付宝系统发送该交易状态通知
            }
            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

            echo "success";		//请不要修改或删除

        }else {
            //验证失败
            echo "fail";	//请不要修改或删除

        }
    }
}



